import numpy as np
import matplotlib.pyplot as plt

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import time
import random
# from parking import select_path
# from parking import constants as cons
import select_path
import constants as cons
import file_utils
import utils_move_plot as ump
import move_in_policy


def up_and_right(point, base_point):
    if point[1] > base_point[1]:
        return False
    elif point[1] < base_point[1]:
        return True
    else:  # 如果出现在枝干上....
        pass


def get_circle_neighbors_one_step(target, free_point, occ=None):
    # 只有两行，叶子节点直接紧挨着枝干，该策略只适用于 target 临近枝干的情况
    # 按照 横坐标，纵坐标 由小到大的顺序
    width = np.abs(target[0] - free_point[0]) + 1
    height = np.abs(target[1] - free_point[1]) + 1
    min_x = np.minimum(target[0], free_point[0])
    min_y = np.minimum(target[1], free_point[1])
    neighbors = []
    for h in range(height):
        for w in range(width):
            point = [min_x + w, min_y + h]
            # if occ and point in occ:
            #     neighbors.append(point)
            neighbors.append(point)

    # 多两行：只计算四条边，普适性。

    return neighbors


# get_circle_neighbors_one_step([1, 2], [4, 1])

def get_circle_neighbors_setp4(free_point, target):
    '''
    四步移出    以 free_point 为中心点
    统一向靠近枝干一侧寻找最小循环点, right:True  up: True
    :param point:
    :param target:
    :return:
    '''
    neighbor_1, neighbor_2 = '', ''
    out = cons.pos_out[0]
    if free_point[0] < out[0]:  # 向右发展，横坐标加一
        neighbor_1 = [[free_point[0] + 1, free_point[1]], cons.no_moved]
        neighbor_2 = [[target[0] + 1, target[1]], cons.no_moved]

    elif free_point[0] < out[0]:  # 向左发展，横坐标减一
        neighbor_1 = [[free_point[0] - 1, free_point[1]], cons.no_moved]
        neighbor_2 = [[target[0] - 1, target[1]], cons.no_moved]
    else:
        pass

    return neighbor_1, neighbor_2


def get_circle_neighbors_setp5(free_point, target):
    '''
    五步移出     以 target 为中心点
    统一向靠近枝干一侧寻找最小循环点, right:True  up: True
    :param point:
    :param target:
    :return:
    '''
    neighbor_1, neighbor_2, neighbor_3, neighbor_4 = '', '', '', ''
    out = cons.pos_out[0]
    if free_point[1] > out[1]:  # 向右发展，横坐标加一
        neighbor_1 = [[target[0] + 1, target[1]], cons.no_moved]
        neighbor_2 = [[target[0] + 1, target[1] + 1], cons.no_moved]
        neighbor_3 = [[target[0], target[1] + 1], cons.no_moved]
        neighbor_4 = [[target[0] - 1, target[1] + 1], cons.no_moved]

    elif free_point[1] > out[1]:  # 向左发展，横坐标减一
        neighbor_1 = [[target[0] - 1, target[1]], cons.no_moved]
        neighbor_2 = [[target[0] - 1, target[1] + 1], cons.no_moved]
        neighbor_3 = [[target[0], target[1] + 1], cons.no_moved]
        neighbor_4 = [[target[0] + 1, target[1] + 1], cons.no_moved]
    else:
        pass

    return neighbor_1, neighbor_2, neighbor_3, neighbor_4


def circle_move():
    # 不需要 == 构建链表，循环链表 或者 构建数组，数组排序
    print('here is todo')

    pass


def check_obstacle_position(trace, occ):
    '''
    检查路径上是否有被占用的车位
    :param trace: [[pos], [pos], [pos]]
    :param occ: list of [pos]
    :return:
    '''
    for item in trace:
        if item in occ:
            return False
    return True


def check_obstacle(trace, occ, obstacle=None):
    # 检查路径上是否存在障碍
    # 处理 trace: [ [ [], [], [target] ],   [[], [], []]  ] 三层
    # target: 第一个路径的最后一个位置
    '''

    :param trace:
    :param occ:
    :param obstacle:
    :return:
    points: 余下的移出路径
    '''
    if len(np.array(trace).shape) == 2:
        points_obstacle = []
        # [[], [], []]
        for item in trace:
            if item in occ:
                points_obstacle.append(item)
        points = trace
        return points, points_obstacle
        pass
    if len(np.array(trace).shape) == 3:
        points = []
        points_obstacle = []
        target = 1
        for item_1 in trace:
            for item_2 in item_1:
                # if target:                              # 过滤掉target
                #     target = 0
                #     continue
                if obstacle and item_2 == obstacle:  # 沿着路径到某个点，返回该点之前的障碍点
                    break
                if item_2 in occ:
                    points_obstacle.append(item_2)  # 保存障碍点
                points.append(item_2)  # 保存路径上所有点（不包含target）
        return points, points_obstacle


def get_point_key(point, pre="", suf=""):
    result = ''
    if pre:
        result = pre + '_' + str(point[0]) + '_' + str(point[1])
    else:
        result = str(point[0]) + '_' + str(point[1])
    if suf:
        result = result + '_' + suf

    return result


def save_trace(point, trace, all_trace={}):
    # 保存运动的路径
    point_key = get_point_key(point)
    all_trace.update({point_key: trace})
    file_utils.modify_file(cons.trace_file, {point_key: trace}, cons.add)
    return all_trace


def get_trace(point, all_trace):
    # 获取轨迹
    trace = ''
    point_key = get_point_key(point)
    trace = all_trace.get(point_key)
    return trace


def construct_free_queue(occupied):
    free = []
    for x in range(cons.axis_width):
        for y in range(cons.axis_height):
            if [x, y] not in cons.pos_in and [x, y] not in cons.pos_out and [x, y] not in occupied:
                free.append([x, y])

    return free


def get_random_out():
    '''
    多出入口的情况下，随机选择出入口
    :return: pos_in, pos_out
    '''
    index_in = np.random.randint(0, len(cons.pos_in), 1)
    pos_in = cons.pos_in[index_in]
    index_out = np.random.randint(0, len(cons.pos_out), 1)
    pos_out = cons.pos_out[index_out]
    return pos_in, pos_out


def init_figure():
    '''
    初始化画布信息，为每个位置设置相关参数,
    【未去除出入口位置的相关参数】
    {position_1_0: {
        'node_info': 'root_node',
        'cost_energy': 1.0,
        'importance_level': 4.0,
        'occupied_info': 'other',
        'cost_time': 1.0,
        'cost_distance': 1.0}}
    :return:
    '''
    length = int((cons.axis_num * cons.axis_alpha) / 10)
    fig_dicts_ = {}
    cost = {}
    node_queue = []
    for x in range(cons.axis_width):
        for y in range(cons.axis_height):
            key, value, cost_total = get_position_info(x, y, node_queue=node_queue)
            fig_dicts_.update({key: value})
            cost.update({"cost_%s_%s" % (x, y): cost_total})
            node_queue.append([x, y])
    return fig_dicts_, cost


def get_init_position():
    '''
    获取初始化位置
    :return:
    '''
    return cons.pos_out[0]


def get_pos_out_x():
    '''
    得到所有出口的横坐标
    :return:
    '''
    x_list = list()
    for item in cons.pos_out:
        if item[0] not in x_list:
            x_list.append(item[0])
    return x_list
    pass


def get_pos_out_y():
    '''
    得到所有出口的纵坐标
    :return:
    '''
    y_list = list()
    for item in cons.pos_out:
        if item[1] not in y_list:
            y_list.append(item[1])
    return y_list
    pass


def get_tmp_occupied(in_out=None):
    # 将除 in_out 之外的所有的叶子节点设为被占有状态
    tmp_occupied = []
    for pos_x in range(cons.axis_width):
        for pos_y in range(cons.axis_height):
            pos_info = check_position_info(pos_x, pos_y)
            if pos_info == cons.node_leaf:
                tmp_occupied.append([pos_x, pos_y])
    if in_out and in_out in tmp_occupied:
        tmp_occupied.remove(in_out)
        if in_out[0] + 1 in get_pos_out_x() or in_out[0] - 1 in get_pos_out_x():
            if [in_out[0], in_out[1] + 1] not in tmp_occupied:
                tmp_occupied.append([in_out[0], in_out[1] + 1])  # add up / down sub root node to occupied
            if [in_out[0], in_out[1] - 1] not in tmp_occupied:
                tmp_occupied.append([in_out[0], in_out[1] - 1])
            pass

        if check_position_info(in_out[0] + 1, in_out[1]) == cons.node_sub_root or \
                check_position_info(in_out[0] - 1,
                                    in_out[1]) == cons.node_sub_root:  # right / left side pos is a sub root node
            if [in_out[0], in_out[1] + 1] not in tmp_occupied:
                tmp_occupied.append([in_out[0], in_out[1] + 1])  # add up / down sub root node to occupied
            if [in_out[0], in_out[1] - 1] not in tmp_occupied:
                tmp_occupied.append([in_out[0], in_out[1] - 1])

        # elif check_position_info(in_out[0], in_out[1]) == cons.node_sub_root:
        #     tmp_occupied.append([in_out[0], in_out[1]])

    return tmp_occupied


def init_trace():
    '''
    初始化路径，固定进出的路径信息
    all_trace: {'point': [[pos], [pos], [pos], [pos]]}
    :return:
    '''
    all_trace = {}
    init = get_init_position()
    for pos_x in range(cons.axis_width):
        for pos_y in range(cons.axis_height):
            pos = [pos_x, pos_y]
            tmp_occupied = get_tmp_occupied(pos)
            trace = select_path.select_path(init, pos, tmp_occupied, state='in')
            point_key = get_point_key(pos)
            all_trace.update({point_key: trace})
    file_utils.modify_file(cons.trace_file, all_trace, cons.add)


# 先进先出的策略
# 根据重要性程度和距离出口的远近得到代价的排序
def get_init_scores(fig_dicts):
    # for position in

    pass


def get_sub_root_node():
    '''
    得到出入口的位置参数，无重复
    :return:
    '''
    sub_root_node_x = []
    sub_root_node_y = []
    for item in cons.pos_in:
        sub_root_node_x.append(item[0])
        sub_root_node_y.append(item[1])

    for item in cons.pos_out:
        sub_root_node_x.append(item[0])
        sub_root_node_y.append(item[1])

    return list(set(sub_root_node_x)), list(set(sub_root_node_y))


def check_position_info(pos_x, pos_y=None):
    '''
    检查叶子节点的行中是否存在子根节点
    :param pos_x:
    :param pos_y:
    :return:
    '''
    sub_root_node_x, sub_root_node_y = get_sub_root_node()
    node_info = ''
    # if pos_x in sub_root_node and pos_y in sub_root_node:
    pos = [pos_x, pos_y]
    if pos in cons.pos_in or pos in cons.pos_out:
        node_info = cons.node_root
    elif pos_y % 3 == 0 or pos_y % 3 == 2:
        node_info = cons.node_leaf
        if cons.is_border_clear:  # 靠近边界的一个车道是否通车
            if pos_x in sub_root_node_x or pos_y == cons.axis_height - 1:
                node_info = cons.node_sub_root

        else:
            if pos_x == 0 or pos_x == int(cons.axis_num * cons.axis_alpha / 10 - 1):
                node_info = cons.node_leaf
            else:
                if pos_x in sub_root_node_x or pos_y == cons.axis_height - 1:
                    node_info = cons.node_sub_root
    else:
        node_info = cons.node_sub_root
    return node_info


def is_main_sub_root_node(node, v=False, h=False):
    '''

    :param node:
    :param v: 在竖直方向上
    :param h: 在水平方向上
    :return:
    '''
    for item in cons.pos_out:
        if item[0] == node[0]:
            return True
    return False
    pass


def get_distance_to_out(from_pos):
    '''
    根据出口计算距离
    :param from_pos:
    :return: {out_%s_%s: value, out_%s_%s: value, out_%s_%s: value}
    '''
    out = cons.pos_out
    out_distance = {}
    for item in out:
        out_key = "out_%s_%s" % (item[0], item[1])
        out_value = Manhattan_distance(from_pos, item)
        out_distance.update({out_key: out_value})
    return out_distance


def get_node_father():
    pass


def get_node_child_father(up, down, left, right, node_queue, pos_info="child"):
    '''
    :param up:
    :param down:
    :param left:
    :param right:
    :param node_queue: queue of root node and sub-root node
    :param pos_info: one of node_root, node_sub_root, node_leaf
    :return: list of child node and father node
    '''
    child = []
    father = []
    for item in [up, down, left, right]:
        if pos_info == cons.node_root:  # 没有父节点
            if item != None:
                child.append(item)
        elif pos_info == cons.node_sub_root:
            if item in node_queue:
                father.append(item)
            elif item != None:
                child.append(item)
        elif pos_info == cons.node_leaf:  # 没有子节点
            if item in node_queue:
                father.append(item)
        else:
            print("error in get node child and father")

    return father, child


def is_node_father():
    pass


def is_node_child():
    pass


def get_neighbors(pos_x, pos_y):
    left = [pos_x - 1, pos_y] if (pos_x - 1 >= 0) else None
    down = [pos_x, pos_y - 1] if (pos_y - 1 >= 0) else None
    right = [pos_x + 1, pos_y] if (pos_x + 1 < cons.axis_width) else None
    up = [pos_x, pos_y + 1] if (pos_y + 1 < cons.axis_height) else None
    return up, down, left, right


def get_node_level(pos_x, pos_y, pos_info, node_queue):
    '''
    根据坐标得到其父节点还是子节点
    :param pos_x:
    :param pos_y:
    :param pos_info: 该位置本身的节点信息，根节点、子根节点、叶节点
    :return:
    '''
    up, down, left, right = get_neighbors(pos_x, pos_y)
    father_nodes, child_nodes = get_node_child_father(up, down, left, right, node_queue, pos_info=pos_info)
    father_nodes = {cons.node_father: father_nodes}  # 父节点
    child_nodes = {cons.node_child: child_nodes}  # 子节点
    # if pos_info == cons.node_root:          # 没有父节点
    #     _, child_nodes = get_node_child(up, down, left, right, node_queue, pos_info=pos_info)
    # elif pos_info == cons.node_sub_root:
    #     father_nodes, child_nodes = get_node_child(up, down, left, right, node_queue, pos_info=pos_info)
    # elif pos_info ==cons.node_leaf:         # 没有子节点
    #     father_nodes, _ = get_node_child(up, down, left, right, node_queue, pos_info=pos_info)
    #     print("node: (%s, %s) is a leaf node" % (pos_x, pos_y))
    # else:
    #     print("no type for node (%s, %s)" % (pos_x, pos_y))
    return father_nodes, child_nodes
    pass


def get_position_info(pos_x, pos_y, node_queue, in_out=None):
    '''
    根据位置信息，得到位置信息
    :param pos:
    :return:
    '''
    value = {}
    position_key = cons.position_key % (pos_x, pos_y)
    # 故障信息
    value.update({cons.breakdown_info: cons.breakdown_no})
    # 车辆停放状态
    value.update({cons.occupied_info: cons.occupied_other})
    # 时间代价
    value.update({cons.cost_time: cons.cost_time_default})

    # 能量代价
    value.update({cons.cost_energy: cons.cost_energy_default})

    score = cons.cost_time_default * cons.cost_time_rate + \
            cons.cost_energy_default * cons.cost_energy_rate

    # 节点状态，重要性程度级别
    # 根节点，子节点。1、判断是否为根节点（出入口） 2、判断是否为子根节点 3、在子节点的行判断是否有子根节点
    pos_info = check_position_info(pos_x, pos_y)
    if pos_info == cons.node_root:
        value.update({cons.node_info: cons.node_root})
        value.update({cons.importance_level: cons.importance_score_root})
        score += cons.importance_score_root * cons.importance_info_rate
    elif pos_info == cons.node_sub_root:  # 子根节点
        value.update({cons.node_info: cons.node_sub_root})
        value.update({cons.importance_level: cons.importance_score_sub_root})
        score += cons.importance_score_sub_root * cons.importance_info_rate
    elif pos_info == cons.node_leaf:  # 叶子节点
        value.update({cons.node_info: cons.node_leaf})
        value.update({cons.importance_level: cons.importance_score_leaf})
        score += cons.importance_score_leaf * cons.importance_info_rate
    else:
        raise Exception("can't init node info")

    # 保存其父节点、子节点信息
    father_nodes, child_nodes = get_node_level(pos_x, pos_y, pos_info, node_queue=node_queue)
    value.update(father_nodes)
    value.update(child_nodes)

    # 根据距离细化重要性程度

    # 距离出口的代价
    # 得分 # cons.cost_distance_default * distance + \
    # cons.cost_distance_default * cons.cost_distance_default

    distance_to_out = get_distance_to_out([pos_x, pos_y])
    # value.update({cons.cost_distance: distance})
    out = cons.pos_out
    cost_total = {}
    for item in out:
        out_key = cons.out_key % (item[0], item[1])
        distance_key = cons.cost_total_key % (item[0], item[1])
        cost_total.update({distance_key: score + distance_to_out[out_key]})

    value.update({cons.cost_distance: cost_total})

    return position_key, value, cost_total


def sort_by_value(dicts, reverse, node_info=cons.node_leaf):
    items = dicts.items()
    lists = []
    for key, value in items:
        pos_out = key[-7:]
        position_x, position_y = int(pos_out.split('_')[0]), int(pos_out.split('_')[1])
        cost = value[cons.queue_in_cost]
        importance = value[cons.queue_in_importance]
        if node_info == cons.node_leaf:
            lists.append([importance, cost, pos_out, position_y])

        elif node_info == cons.node_sub_root:
            lists.append([importance, cost, pos_out, position_y])
    # 排序
    if node_info == cons.node_leaf:
        lists.sort(reverse=reverse)

    elif node_info == cons.node_sub_root:
        lists.sort(key=lambda x: x[1], reverse=not reverse)
        lists.sort(key=lambda x: x[3], reverse=reverse)
    elif node_info == cons.node_main_sub_root:
        print('node main sub root.')
        pass
    return lists


def get_cost_queue_in(fig_dicts=None, fig_costs=None):
    '''
    获取cost队列
    需要去除 出入口 的部分
    :param
    fig_dicts:{}
    :param 
    fig_costs: {
        cost_0_0: {cost_total_0_9: 15.0, cost_total_5_9: 20.0},
        cost_0_0: {cost_total_0_9: 15.0, cost_total_5_9: 20.0},
        cost_0_0: {cost_total_0_9: 15.0, cost_total_5_9: 20.0}
    }
    :return:
    '''
    queue = {}
    sub_root_queue = {}
    main_sub_root_queue = {}
    leaf_queue = {}

    if not fig_costs or not fig_dicts:
        fig_dicts, fig_costs = init_figure()
    for key, value in fig_dicts.items():
        important_info = value[cons.importance_level]

        pos_1, pos_2 = int(key.split('_')[1]), int(key.split('_')[2])
        node_info = check_position_info(pos_1, pos_2)

        cost_total = value[cons.cost_distance]

        for cost_total_key in cost_total.keys():
            queue_in_key = cons.queue_in + key.split('position')[-1] + cost_total_key.split('total')[-1]
            score = cost_total[cost_total_key]

            if node_info == cons.node_sub_root:
                for item in cons.pos_out:
                    # pos_1 == item[0]
                    # pos_2 == item[1] and pos_1 == 0
                    # pos_2 == item[1] and pos_1 == 9
                    if pos_1 == item[0]:  # 判断是否是更为主要的子根节点
                        main_sub_root_queue.update({queue_in_key: {cons.queue_in_cost: score,
                                                                   cons.queue_in_importance: important_info}})
                    else:
                        sub_root_queue.update({queue_in_key: {cons.queue_in_cost: score,
                                                              cons.queue_in_importance: important_info}})
            elif node_info == cons.node_leaf:
                # {queue_cost_0_0_0_9: 15.0, queue_important_0_9: 2} cost_posx_posy_outx_outy
                leaf_queue.update({queue_in_key: {cons.queue_in_cost: score,
                                                  cons.queue_in_importance: important_info}})

    # 无序的dict转换为有序的list
    leaf_queue = sort_by_value(leaf_queue, reverse=False, node_info=cons.node_leaf)
    sub_root_queue = sort_by_value(sub_root_queue, reverse=False, node_info=cons.node_sub_root)
    main_sub_root_queue = sort_by_value(main_sub_root_queue, reverse=False, node_info=cons.node_sub_root)

    # 整合两个队列，形成最终的队列
    leaf_queue.extend(sub_root_queue)
    leaf_queue.extend(main_sub_root_queue)

    return leaf_queue


def get_pair_occupied(out_, in_out, occupied):
    '''
    # 得到已经被占得停车位坐标
    # out_: 即将被 停车 / 移车 的位置
    # in_out: 是 停车 / 移车
    :param out_:
    :param in_out:
    :return:
    '''
    if out_ is not False:
        if in_out:  # 停车
            occupied.append(out_)
        elif not in_out:  # 移车
            # 弹出
            occupied.pop(occupied.index(out_))
    return occupied


def out_pair(occ_pair, occ):
    if len(occ) == 0:
        print("there is no car in the park.")
        return False
    if occ_pair not in occ:
        print("there is no car in the position %s " % occ_pair)
        return False
    print('move out %s' % occ_pair)
    return True


def get_min_cost_position(pos, free_queue, occ):
    '''
    找到 pos 与 free_queue 中元素开销最小的 item
    :param pos: 源位置
    :param free_queue: 可以使用的车位队列
    :param occ: 被占的车位
    :return:
        min_score: 最小开销
        out_pos: 最小开销对应的坐标
        out_trace: 将该点移到 out_pos 的路径
    '''
    out_scores = []
    min_score = 10000.0
    out_pos, out_trace = '', ''
    # 处理当源位置在 occupied 中，出现找不到 源位置、目标位置 的情况
    # flag = False
    # if pos in occ:
    #     flag = True
    #     occ.remove(pos)
    for i, item in enumerate(free_queue):
        trace = select_path.select_path(pos, item, occ, state='remove')
        if not trace:
            continue
        score = compute_distance_score(trace)
        if score < min_score:
            min_score = score
            out_pos = item
            out_trace = trace
        out_scores.append([score, item])
    # if flag:
    #     occ.append(pos)
    return min_score, out_pos, out_trace


def computer_energy_score(trace):
    '''
    每个过程 一次取车，一次放车，多次移车
    :param trace:
    :return:
    '''
    energy_cost = 0
    energy_cost += cons.cost_energy_up  # 取车
    energy_cost += cons.cost_energy_down  # 放车

    energy_cost += cons.cost_energy_move_with_car * (len(trace) - 1)  # 移车

    return energy_cost


def compute_distance_score(trace, use_important_level=False):
    '''
    根据所经过的轨迹计算距离
    :param trace:
    :return:
    '''
    if use_important_level:
        distance = 0
        time_cost = 0
        for item in trace:
            level = check_position_info(item[0], item[1])
            if level == cons.node_root:
                distance += cons.importance_score_root * cons.importance_info_rate
            elif level == cons.node_sub_root:  # 子根节点
                distance += cons.importance_score_sub_root * cons.importance_info_rate
            elif level == cons.node_leaf:  # 叶子节点
                distance += cons.importance_score_leaf * cons.importance_info_rate
            else:
                raise Exception("can't init node info")
            time_cost += cons.cost_time_default * cons.cost_time_rate
    else:
        distance = len(trace) * 1.0
        time_cost = cons.cost_time_default * cons.cost_time_rate * len(trace)

    return distance, time_cost


def Manhattan_distance(position_1, position_2):
    '''
    https://blog.csdn.net/jacke121/article/details/54585685
    :param position_1:
    :param position_2:
    :return:
    '''
    return np.abs(position_1[0] - position_2[0]) + np.abs(position_1[1] - position_2[1])


def select_shortest_position(init, target, occupied):
    # 根据初始位置，获取周边位置
    positions = []
    select_position = []
    if init[0] - 1 >= 0:
        positions.append([np.maximum(init[0] - 1, 0), init[1]])
    if init[1] - 1 >= 0:
        positions.append([init[0], np.maximum(init[1] - 1, 0)])
    positions.append([init[0] + 1, init[1]])
    positions.append([init[0], init[1] + 1])
    minium = 1000
    for position in positions:
        if position in occupied:
            continue
        temp = Manhattan_distance(position, target)
        if minium > temp:
            minium = temp
            select_position.append(position)
    return select_position[-1]


def plot_pause():
    fig = plt.figure()
    ax = fig.subplots()
    # plt.ion()
    # ax.axis([0, 2, 0, 2])
    pair = [[1, 5], [5, 5], [10, 5], [10, 10]]
    # 根据轨迹点得到轨迹图
    for i in range(len(pair) - 1):
        try:
            ax.lines.remove(lines[0])
            pass
        except Exception:
            pass
        ax.axis([0, 20, 0, 20])
        lines = ax.plot(pair[i], pair[i + 1])
        plt.pause(1)
    # plt.show()    # 不能使用show()函数


def random_inout(ratio=1 / 3):
    '''
    ratio: 出车占的比例
    :param ratio:
    :return:
    '''
    num = random.random()
    if num > ratio:
        return True  # in
    else:
        return False  # out
